package com.jctrip.hotel.source.service.rezen.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.google.common.collect.Lists;
import com.jctrip.hotel.domain.entity.*;
import com.jctrip.hotel.source.model.rezen.req.HotelDetailsReq;
import com.jctrip.hotel.source.model.rezen.req.ProductBriefListByCompanyIdReq;
import com.jctrip.hotel.source.model.rezen.req.ProductListByCompanyIdReq;
import com.jctrip.hotel.source.model.rezen.resp.*;
import com.jctrip.hotel.source.mq.IncrHotelRocketMqProducer;
import com.jctrip.hotel.source.service.basic.*;
import com.jctrip.hotel.source.xxl.rezen.thread.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.jctrip.hotel.common.constant.RedisKeyConstant;
import com.jctrip.hotel.common.constant.XxlJobNameConstant;
import com.jctrip.hotel.common.enums.SourceEnum;
import com.jctrip.hotel.common.threadpool.XxlJobThreadPool;
import com.jctrip.hotel.common.util.DateUtil;
import com.jctrip.hotel.common.util.JsonUtil;
import com.jctrip.hotel.common.util.PriceUtil;
import com.jctrip.hotel.common.util.RedisUtil;
import com.jctrip.hotel.domain.dao.HtHotelStdInfoDao;
import com.jctrip.hotel.source.model.rezen.resp.CityInfoDTO.CityInfoData;
import com.jctrip.hotel.source.model.rezen.resp.HotelInfoDTO.Amenities;
import com.jctrip.hotel.source.model.rezen.resp.ProductListDTO.BreakfastList;
import com.jctrip.hotel.source.model.rezen.resp.ProductListDTO.CancelRuleList;
import com.jctrip.hotel.source.model.rezen.resp.ProductListDTO.ProductList;
import com.jctrip.hotel.source.model.rezen.resp.ProductListDTO.RoomCancelRuleList;
import com.jctrip.hotel.source.model.rezen.resp.ProductListDTO.RoomInventoryList;
import com.jctrip.hotel.source.model.rezen.resp.ProductListDTO.RoomPriceList;
import com.jctrip.hotel.source.model.rezen.resp.RoomTypeDTO.RoomType;
import com.jctrip.hotel.source.service.rezen.RezenService;
import com.jctrip.hotel.source.service.rezen.RezenTaskService;

import lombok.extern.slf4j.Slf4j;

/**
 * @Author henry
 * @Date 2023/8/12 11:29
 * @Description
 */
@Service
@Slf4j
public class RezenTaskServiceImpl implements RezenTaskService {
    private static final XxlJobThreadPool syncRezenRatesTaskPopPol =
            new XxlJobThreadPool(XxlJobNameConstant.SYNC_REZEN_RATES_POP);
    private static final XxlJobThreadPool syncRezenHotelListPullPol =
            new XxlJobThreadPool(XxlJobNameConstant.SYNC_REZEN_HOTEL_LIST_PUll);
    private static final XxlJobThreadPool syncRezenAllRatesTaskPopPol =
            new XxlJobThreadPool(XxlJobNameConstant.SYNC_REZEN_ALL_RATES_POP);
    private static final XxlJobThreadPool syncRezencoHotelListPopPol =
            new XxlJobThreadPool(XxlJobNameConstant.SYNC_REZENCO_HOTEL_LIST_POP);
    private static final XxlJobThreadPool syncRezencoRatesTaskPopPol =
            new XxlJobThreadPool(XxlJobNameConstant.SYNC_REZENCO_RATES_POP);
    private static final XxlJobThreadPool syncRezenImgListTaskPopPol =
            new XxlJobThreadPool(XxlJobNameConstant.SYNC_REZEN_IMG_LIST_POP);
    private static final long PUSH_EXPIRY = 1 * 60;
    private final static Integer QPS_COUNT = 1;
    private final static Long TIME_OUT = 2000L;
    @Resource
    private RezenService rezenService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private HtHotelStdInfoService htHotelStdInfoService;
    @Resource
    private HtRoomTypeStdInfoService htRoomTypeStdInfoService;
    @Resource
    private HtHotelStdInfoDao htHotelStdInfoDao;
    @Resource
    private HtPriceCalendarService htPriceCalendarService;
    @Resource
    private HtPriceCalendarRezenService htPriceCalendarRezenService;

    @Resource
    private HtHotelImageRezenService htHotelImageRezenService;

    @Resource
    private HtHotelStdInfoRezencoService htHotelStdInfoRezencoService;

    @Resource
    private HtRoomTypeStdInfoRezencoService htRoomTypeStdInfoRezencoService;

    @Resource
    private HtPriceCalendarRezencoService htPriceCalendarRezencoService;
    @Resource
    private HtSourceInfoService htSourceInfoService;

    @Resource
    private HtHotelStdImageService htHotelStdImageService;
    @Autowired
    private IncrHotelRocketMqProducer incrHotelRocketMqProducer;

    @Override
    public void syncRezenCityListTaskPull(String secretId, String secretKey, Long groupId) {
        try {
            if (redisUtil.setENx(RedisKeyConstant.HOTEL_MAIN_REZEN_CITYID_PUSH, PUSH_EXPIRY,
                    RedisKeyConstant.HOTEL_MAIN_REZEN_CITYID_PUSH)) {
                // todo 更新接口，直接获取所有酒店id
                List<HotelInfoIdDTO> hotelInfoIdDTOS = rezenService.queryHotelList2(secretId, secretKey, groupId);
                redisUtil.leftPushAll(RedisKeyConstant.HOTEL_MAIN_REZEN_CITYID_LIST,
                        hotelInfoIdDTOS.stream().map(HotelInfoIdDTO::getHotelId).collect(Collectors.toList()));
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    public void syncRezenCityListFastTaskPull(String secretId, String secretKey, Long groupId) {
        syncRezenHotelListPullPol.execute(() -> new SyncRezenHotelListPullThread(secretId, secretKey, groupId));
    }

    @Override
    public void syncRezenCityListTaskPull(String secretId, String secretKey, Long groupId, Long hotelId) {
        // do something
        try {
            // 拿不到给我一直试
            while (true) {
                // 看看有没有被限流
                if (StringUtils.isNotBlank(
                        redisUtil.acquireToken(RedisKeyConstant.HOTEL_MAIN_REZEN_STATIC_INFO_LIMIT_LOCK,
                                QPS_COUNT,
                                TIME_OUT))) {
                    // 酒店信息查询
                    HotelDetailsReq req = HotelDetailsReq.builder()
                            .hotelId(hotelId)
                            .groupId(groupId)
                            .build();
                    HotelDetailsResp hotel = rezenService.queryHotelDetails(req, secretId, secretKey);
                    if (hotel == null) {
                        return;
                    }
                    HtHotelStdInfo htHotelStdInfo = parseHotelInfoData(hotel);
                    LambdaUpdateWrapper<HtHotelStdInfo> wrapper = new LambdaUpdateWrapper<>();
                    wrapper.set(HtHotelStdInfo::getSourceStatus, htHotelStdInfo.getSourceStatus());
                    wrapper.set(HtHotelStdInfo::getSupportRestaurant, htHotelStdInfo.getSupportRestaurant());
                    wrapper.eq(HtHotelStdInfo::getHotelId, htHotelStdInfo.getHotelId());
                    // 基础信息
                    htHotelStdInfoService.saveOrUpdate(htHotelStdInfo, wrapper);
                    // 限流处理:休眠
                    Thread.sleep(1000L);
                    // 查询房型
                    List<RoomType> roomTypeList = rezenService.queryRoomType(secretId, secretKey, groupId, hotel.getHotelId());
                    Optional.ofNullable(roomTypeList).orElse(new ArrayList<>()).forEach(roomType -> {
                        // 房型
                        HtRoomTypeStdInfo htRoomTypeStdInfo = new HtRoomTypeStdInfo();
                        htRoomTypeStdInfo.setHotelId(htHotelStdInfo.getHotelId());
                        htRoomTypeStdInfo.setRoomTypeName(roomType.getRoomtypNm());
                        htRoomTypeStdInfo.setRoomTypeCode(String.valueOf(roomType.getRoomtypId()));
                        htRoomTypeStdInfo.setRoomArea(roomType.getRoomArea());
                        htRoomTypeStdInfo.setMaxCheckIn(roomType.getOccupancyMax());
                        htRoomTypeStdInfo.setFloor(roomType.getRoomFloors());
                        Integer windowType = null;
                        if (roomType.getWindowType() != null) {
                            switch (roomType.getWindowType()) {
                                case 101:
                                    windowType = 1;
                                    break;
                                case 102:
                                    windowType = 0;
                                    break;
                                case 103:
                                    windowType = 2;
                                    break;
                                default:
                                    break;
                            }
                        }
                        htRoomTypeStdInfo.setWindowType(windowType);
                        Integer bedType = null;
                        if (CollectionUtils.isNotEmpty(roomType.getBedTypeList())) {
                            if (roomType.getBedTypeList().size() == 1) {
                                switch (roomType.getBedTypeList().get(0).getEntityNm()) {
                                    case "大床":
                                        bedType = 0;
                                        break;
                                    case "双人床":
                                        bedType = 4;
                                        break;
                                    case "单人床":
                                        bedType = 1;
                                        break;
                                    case "特大床":
                                        bedType = 3;
                                        break;
                                    default:
                                        break;
                                }
                            } else {
                                bedType = 5;
                            }

                        }
                        htRoomTypeStdInfo.setBedType(bedType);
                        htRoomTypeStdInfoService.saveOrUpdate(htRoomTypeStdInfo,
                                new LambdaQueryWrapper<HtRoomTypeStdInfo>().eq(HtRoomTypeStdInfo::getHotelId,
                                                htRoomTypeStdInfo.getHotelId())
                                        .eq(HtRoomTypeStdInfo::getRoomTypeCode, htRoomTypeStdInfo.getRoomTypeCode()));
                    });
                }
                break;
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

    }

    @Override
    public void syncRezenRatesTaskPush() {
        try {
            List<HtHotelStdInfo> htHotelStdInfos = htHotelStdInfoDao.selectList(
                    new LambdaQueryWrapper<HtHotelStdInfo>().eq(HtHotelStdInfo::getSourceCode,
                                    SourceEnum.REZEN.getCode()).eq(HtHotelStdInfo::getSourceStatus, 1)
                            .eq(HtHotelStdInfo::getBookStatus, 1));
            if (CollectionUtils.isNotEmpty(htHotelStdInfos)
                    && redisUtil.lGetListSize(RedisKeyConstant.HOTEL_MAIN_REZEN_RATES_LIST) <= 0) {
                redisUtil.leftPushAll(RedisKeyConstant.HOTEL_MAIN_REZEN_RATES_LIST,
                        htHotelStdInfos.stream().map(HtHotelStdInfo::getHotelId).collect(Collectors.toList()));
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    public void syncRezenRatesTaskFastPop(String secretId, String secretKey, Long groupId, Long productId,
                                          Integer days) {
        syncRezenRatesTaskPopPol.execute(
                () -> new SyncRezenRatesPullThread(secretId, secretKey, groupId, productId, days));
    }

    @Override
    public void syncRezenRatesTaskPop(String secretId, String secretKey, Long groupId, Long hotelId, Long productId,
                                      String start, String end) {
        ProductListDTO roomStatus = rezenService.getRoomStatus(secretId, secretKey, groupId, hotelId, null, start, end);
        if (roomStatus == null) {
            return;
        }

        HtHotelStdInfo htHotelStdInfo = htHotelStdInfoDao.selectOne(
                new LambdaQueryWrapper<HtHotelStdInfo>().eq(HtHotelStdInfo::getHotelId,
                        rezenService.parseInnId(hotelId)));
        List<CancelRuleList> cancelRuleList = roomStatus.getCancelRuleList();
        Optional.ofNullable(roomStatus.getRoomTypeList()).orElse(new ArrayList<>()).forEach(roomStatu -> {
            ProductList productList = Optional.ofNullable(roomStatu.getProductList()).orElse(new ArrayList<>()).stream()
                    .filter(p -> p.getProductId().equals(productId)).findFirst().orElse(null);
            if (productList == null) {
                return;
            }
            // 价格日历
            List<RoomPriceList> roomPriceList = productList.getRoomPriceList();
            if (CollectionUtils.isEmpty(roomPriceList)) {
                return;
            }
            List<RoomInventoryList> roomInventoryList = productList.getRoomInventoryList();
            if (CollectionUtils.isEmpty(roomInventoryList)) {
                return;
            }
            List<RoomCancelRuleList> roomCancelRuleList = productList.getRoomCancelRuleList();
            //
            List<BreakfastList> breakfastList = productList.getBreakfastList();
            roomPriceList.forEach(roomPrice -> {
                // 库存
                RoomInventoryList roomInventory =
                        roomInventoryList.stream().filter(inventory -> inventory.getDay().equals(roomPrice.getDay()))
                                .findFirst().orElse(null);

                // build 参数
                HtPriceCalendar htPriceCalendar = new HtPriceCalendar();
                htPriceCalendar.setHotelId(rezenService.parseInnId(hotelId));
                htPriceCalendar.setRoomTypeCode(String.valueOf(roomStatu.getRoomtypId()));
                htPriceCalendar.setRoomTypeName(roomStatu.getRoomtypNm());
                htPriceCalendar.setCalDate(DateUtil.parseDate(roomPrice.getDay(), "yyyy-MM-dd"));
                htPriceCalendar.setQuota(roomInventory.getAvaRoomCnt());
                htPriceCalendar.setRetailPrice(PriceUtil.fen2yuan(roomPrice.getPrice()));
                htPriceCalendar.setPurchasePrice(PriceUtil.fen2yuan(roomPrice.getPrice()));

                // 早餐
                BreakfastList breakfast = Optional.ofNullable(breakfastList).orElse(new ArrayList<>()).stream()
                        .filter(bf -> bf.getDay().equals(roomPrice.getDay())).findFirst().orElse(null);
                htPriceCalendar.setBreakfastCount(
                        htHotelStdInfo.getSupportRestaurant() == 1 && Objects.nonNull(breakfast)
                                ? breakfast.getBreakfastCnt() : 0);
                RoomCancelRuleList roomCancelRule =
                        Optional.ofNullable(roomCancelRuleList).orElse(new ArrayList<>()).stream()
                                .filter(rule -> rule.getDay().equals(roomPrice.getDay())).findFirst().orElse(null);

                CancelRuleList cancelRule = Optional.ofNullable(cancelRuleList).orElse(new ArrayList<>()).stream()
                        .filter(rule -> Objects.nonNull(roomCancelRule) && rule.getCancelRuleId()
                                .equals(roomCancelRule.getCancelRuleId())).findFirst().orElse(null);

                if (Objects.nonNull(roomCancelRule)) {
                    Integer cancelType = cancelRule.getCancelType();
                    if (cancelType != null) {
                        switch (cancelType) {
                            case 0:
                                cancelType = 2;
                                break;
                            case 1:
                                cancelType = 1;
                                break;
                            case 2:
                                cancelType = 4;
                                break;
                        }
                        htPriceCalendar.setCancelPolicyType(cancelType);
                    }
                    htPriceCalendar.setCancelRule(JsonUtil.toString(roomCancelRule));
                }
                // 保存房态信息
                htPriceCalendarService.saveOrUpdate(htPriceCalendar,
                        new LambdaQueryWrapper<HtPriceCalendar>().eq(HtPriceCalendar::getHotelId,
                                        htPriceCalendar.getHotelId())
                                .eq(HtPriceCalendar::getRoomTypeCode, htPriceCalendar.getRoomTypeCode())
                                .eq(HtPriceCalendar::getCalDate, htPriceCalendar.getCalDate()));
            });

        });
    }

    @Override
    public void syncRezenAllRatesTaskPush() {
        try {
            List<HtHotelStdInfo> htHotelStdInfos = htHotelStdInfoDao.selectList(
                    new LambdaQueryWrapper<HtHotelStdInfo>().eq(HtHotelStdInfo::getSourceCode,
                                    SourceEnum.REZEN.getCode()).eq(HtHotelStdInfo::getSourceStatus, 1)
                            .eq(HtHotelStdInfo::getBookStatus, 1));
            if (CollectionUtils.isNotEmpty(htHotelStdInfos)
                    && redisUtil.lGetListSize(RedisKeyConstant.HOTEL_MAIN_REZEN_ALL_RATES_LIST) <= 0) {
                redisUtil.leftPushAll(RedisKeyConstant.HOTEL_MAIN_REZEN_ALL_RATES_LIST,
                        htHotelStdInfos.stream().map(HtHotelStdInfo::getHotelId).collect(Collectors.toList()));
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    public void syncRezenAllRatesTaskPop(String sourceId, String secretId, String secretKey, Long groupId, Integer days) {
        syncRezenAllRatesTaskPopPol.execute(
                () -> new SyncRezenAllRatesPullThread(sourceId, secretId, secretKey, groupId, days));
    }

    @Override
    public void syncRezenRatesTaskAllPop(String sourceId, String secretId, String secretKey, Long groupId, Long hotelId, String start, String end) {
        // 一律按照库存为1算 然后统一拉出数据处理 防止产品码修改
        htPriceCalendarRezenService.update(
                new LambdaUpdateWrapper<HtPriceCalendarRezen>().set(HtPriceCalendarRezen::getQuota, 1)
                        .eq(HtPriceCalendarRezen::getHotelId, rezenService.parseInnId(hotelId)));
        // 拿不到给我一直试
        while (true) {
            // 看看有没有被限流
            if (StringUtils.isNotBlank(
                    redisUtil.acquireToken(RedisKeyConstant.HOTEL_MAIN_REZEN_ALL_RATES_LIMIT_LOCK,
                            QPS_COUNT,
                            TIME_OUT))) {
                ProductListDTO roomStatus = rezenService.getRoomStatus(secretId, secretKey, groupId, hotelId, null, start, end);
                if (roomStatus == null) {
                    return;
                }

                HtHotelStdInfo htHotelStdInfo = htHotelStdInfoDao.selectOne(
                        new LambdaQueryWrapper<HtHotelStdInfo>().eq(HtHotelStdInfo::getHotelId,
                                rezenService.parseInnId(hotelId)));
                List<CancelRuleList> cancelRuleList = roomStatus.getCancelRuleList();
                Optional.ofNullable(roomStatus.getRoomTypeList()).orElse(new ArrayList<>()).forEach(roomStatu -> {
                    Optional.ofNullable(roomStatu.getProductList()).orElse(new ArrayList<>()).forEach(productList -> {
                        // 产品下线 直接处理下一个
                        if (productList.getStatusFlg() == 0) {
                            return;
                        }
                        // 价格日历
                        List<RoomPriceList> roomPriceList = productList.getRoomPriceList();
                        if (CollectionUtils.isEmpty(roomPriceList)) {
                            return;
                        }
                        List<RoomInventoryList> roomInventoryList = productList.getRoomInventoryList();
                        if (CollectionUtils.isEmpty(roomInventoryList)) {
                            return;
                        }
                        List<RoomCancelRuleList> roomCancelRuleList = productList.getRoomCancelRuleList();
                        //
                        List<BreakfastList> breakfastList = productList.getBreakfastList();
                        roomPriceList.forEach(roomPrice -> {
                            // 判断是否符合的促销类型-单日促销低价。 (无促销价 102：限时抢，103：尾房，104：天天特价)
                            if (!checkPromotionType(roomPrice)) {
                                return;
                            }

                            // 库存
                            RoomInventoryList roomInventory =
                                    roomInventoryList.stream().filter(inventory -> inventory.getDay().equals(roomPrice.getDay()))
                                            .findFirst().orElse(null);

                            // build 参数
                            HtPriceCalendarRezen htPriceCalendarRezen = new HtPriceCalendarRezen();
                            htPriceCalendarRezen.setHotelId(rezenService.parseInnId(hotelId));
                            htPriceCalendarRezen.setRoomTypeCode(String.valueOf(roomStatu.getRoomtypId()));
                            htPriceCalendarRezen.setRoomTypeName(roomStatu.getRoomtypNm());
                            htPriceCalendarRezen.setProductId(String.valueOf(productList.getProductId()));
                            htPriceCalendarRezen.setCalDate(DateUtil.parseDate(roomPrice.getDay(), "yyyy-MM-dd HH:mm:ss"));
                            htPriceCalendarRezen.setQuota(Objects.nonNull(roomInventory) ? roomInventory.getAvaRoomCnt() : 1);
                            htPriceCalendarRezen.setPurchasePrice(PriceUtil.fen2yuan(roomPrice.getPrice()));
                            htPriceCalendarRezen.setSourceId(sourceId);

                            // 早餐
                            BreakfastList breakfast = Optional.ofNullable(breakfastList).orElse(new ArrayList<>()).stream()
                                    .filter(bf -> bf.getDay().equals(roomPrice.getDay())).findFirst().orElse(null);
                            htPriceCalendarRezen.setBreakfastCount(
                                    htHotelStdInfo.getSupportRestaurant() == 1 && Objects.nonNull(breakfast)
                                            ? breakfast.getBreakfastCnt() : 0);
                            RoomCancelRuleList roomCancelRule =
                                    Optional.ofNullable(roomCancelRuleList).orElse(new ArrayList<>()).stream()
                                            .filter(rule -> rule.getDay().equals(roomPrice.getDay())).findFirst().orElse(null);

                            CancelRuleList cancelRule = Optional.ofNullable(cancelRuleList).orElse(new ArrayList<>()).stream()
                                    .filter(rule -> Objects.nonNull(roomCancelRule) && rule.getCancelRuleId()
                                            .equals(roomCancelRule.getCancelRuleId())).findFirst().orElse(null);

                            if (Objects.nonNull(cancelRule)) {
                                Integer cancelType = Optional.ofNullable(cancelRule).orElse(new CancelRuleList()).getCancelType();
                                if (cancelType != null) {
                                    switch (cancelType) {
                                        case 0:
                                            cancelType = 2;
                                            break;
                                        case 1:
                                            cancelType = 1;
                                            break;
                                        case 2:
                                            String type = Optional.ofNullable(cancelRule).orElse(new CancelRuleList()).getCancelRuleItemList()
                                                    .stream().map(ProductListDTO.CancelRuleItemList::getType).findAny().orElse(null);
                                            if ("NO_DEDUCTION".equals(type)) {
                                                cancelType = 4;
                                            } else if ("DEDUCT_BY_PERCENT".equals(type)) {
                                                String time = Optional.ofNullable(cancelRule).orElse(new CancelRuleList()).getCancelRuleItemList()
                                                        .stream().map(ProductListDTO.CancelRuleItemList::getTimeValue).findAny().orElse(null);
                                                htPriceCalendarRezen.setLastCancelTime(DateUtil.parseDate(time, "HH:mm:ss"));
                                                cancelType = 5;
                                            } else if ("DEDUCT_FIRST_NIGHT".equals(type)) {
                                                cancelType = 6;
                                            }
                                            break;
                                        default:
                                            break;
                                    }
                                    htPriceCalendarRezen.setCancelPolicyType(cancelType);

                                }
                                htPriceCalendarRezen.setCancelRule(JsonUtil.toString(roomCancelRule));
                            }
                            // 保存房态信息
                            htPriceCalendarRezenService.saveOrUpdate(htPriceCalendarRezen,
                                    new LambdaQueryWrapper<HtPriceCalendarRezen>()
                                            .eq(HtPriceCalendarRezen::getHotelId, htPriceCalendarRezen.getHotelId())
                                            .eq(HtPriceCalendarRezen::getRoomTypeCode, htPriceCalendarRezen.getRoomTypeCode())
                                            .eq(HtPriceCalendarRezen::getCalDate, htPriceCalendarRezen.getCalDate())
                                            .eq(HtPriceCalendarRezen::getProductId, htPriceCalendarRezen.getProductId())
                                            .eq(HtPriceCalendarRezen::getSourceId, htPriceCalendarRezen.getSourceId()));
                        });
                    });
                });
                break;
            }
        }
        incrHotelRocketMqProducer.send(rezenService.parseInnId(hotelId));
    }

    /**
     * 促销类型（107：连住，106：提前订，102：限时抢，103：尾房，104：天天特价；108：多间立减；213：午夜房）
     * 判断是否符合的促销类型-单日促销低价。 (无促销价 102：限时抢，103：尾房，104：天天特价)
     */
    private boolean checkPromotionType(RoomPriceList roomPrice) {
        // 空促销，底价模式
        if (CollectionUtils.isEmpty(roomPrice.getPromotionList())) {
            return true;
        }
        // 符合的促销类型
        List<Integer> promotionList = Lists.newArrayList(102,103,104);
        for (ProductListDTO.PromotionList promotion : roomPrice.getPromotionList()) {
            // 符合
            if (promotionList.contains(promotion.getPromotionType())) {
                return true;
            }
        }
        // 不符合
        return false;
    }
    @Override
    public void syncRezenImgListTaskPush() {
        try {
            if (redisUtil.setENx(RedisKeyConstant.HOTEL_MAIN_REZEN_IMG_LIST_PUSH, PUSH_EXPIRY,
                    RedisKeyConstant.HOTEL_MAIN_REZEN_IMG_LIST_PUSH)) {
                List<HtHotelStdInfo> htHotelStdInfos = htHotelStdInfoDao.selectList(
                        new LambdaQueryWrapper<HtHotelStdInfo>().eq(HtHotelStdInfo::getSourceCode,
                                        SourceEnum.REZEN.getCode()).eq(HtHotelStdInfo::getSourceStatus, 1)
                                .eq(HtHotelStdInfo::getBookStatus, 1));
                if (CollectionUtils.isNotEmpty(htHotelStdInfos)
                        && redisUtil.lGetListSize(RedisKeyConstant.HOTEL_MAIN_REZEN_IMG_LIST_LIST) <= 0) {
                    redisUtil.leftPushAll(RedisKeyConstant.HOTEL_MAIN_REZEN_IMG_LIST_LIST,
                            htHotelStdInfos.stream().map(HtHotelStdInfo::getHotelId).collect(Collectors.toList()));
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    public void syncRezenImgListTaskPop(String sourceAppId, String sourceSecret, Long groupId) {
        syncRezenImgListTaskPopPol.execute(() -> new SyncRezenImgListTaskThread(sourceAppId, sourceSecret, groupId));
    }

    @Override
    public void syncRezenImgListTask(String secretId, String secretKey, Long groupId, String hotelId) {
        // 保存酒店相关图片
        HotelDetailsResp hotelInfo = null;
        while (true) {
            if (StringUtils.isNotBlank(
                    redisUtil.acquireToken(RedisKeyConstant.HOTEL_MAIN_REZEN_HOTEL_INFO_LIMIT_LOCK,
                            QPS_COUNT,
                            TIME_OUT))) {
                HotelDetailsReq req = HotelDetailsReq.builder()
                        .hotelId(rezenService.parseHotelId(hotelId))
                        .groupId(groupId)
                        .build();
                hotelInfo = rezenService.queryHotelDetails(req, secretId, secretKey);
                break;
            }
        }
        if (hotelInfo == null) {
            return;
        }
        if (CollectionUtils.isEmpty(hotelInfo.getHotelImages())) {
            return;
        }
        List<HtHotelStdImage> hotelImageList = htHotelStdImageService.list(new LambdaQueryWrapper<HtHotelStdImage>()
                .eq(HtHotelStdImage::getHotelId, hotelId)
                .eq(HtHotelStdImage::getImageType, 2));
        if (CollectionUtils.isNotEmpty(hotelImageList)) {
            // 门头图
            String coverImage = hotelInfo.getCoverImage();
            savePicInfo(hotelId, "", 1, coverImage, "");
            // 酒店图片
            List<String> hotelImages = hotelInfo.getHotelImages();
            if (!hotelImages.contains(coverImage)) {
                savePicInfo(hotelId, "", 2, coverImage, "");
            }
            Optional.ofNullable(hotelImages).orElse(new ArrayList<>()).forEach(imgUrl -> {
                savePicInfo(hotelId, "", 2, imgUrl, "");
            });
        }


        // 保存房型相关图片
        List<RoomType> roomTypes = null;
        while (true) {
            if (StringUtils.isNotBlank(
                    redisUtil.acquireToken(RedisKeyConstant.HOTEL_MAIN_REZEN_ROOM_TYPE_INFO_LIMIT_LOCK,
                            QPS_COUNT,
                            TIME_OUT))) {
                roomTypes = rezenService.queryRoomType(secretId, secretKey, groupId, rezenService.parseHotelId(hotelId));
                break;
            }
        }

        Optional.ofNullable(roomTypes).orElse(new ArrayList<>()).forEach(roomStatus -> {
            if (CollectionUtils.isEmpty(roomStatus.getImageList())) {
                return;
            }
            String roomTypeCode = String.valueOf(roomStatus.getRoomtypId());
            List<HtHotelStdImage> roomImages = htHotelStdImageService.list(new LambdaQueryWrapper<HtHotelStdImage>()
                    .eq(HtHotelStdImage::getHotelId, hotelId)
                    .eq(HtHotelStdImage::getRoomTypeCode, roomTypeCode)
                    .eq(HtHotelStdImage::getImageType, 3));
            if (CollectionUtils.isEmpty(roomImages)) {
                String roomImgUrl = roomStatus.getImageList().stream()
                        .filter(e -> e.getFirstFlg() == 1)
                        .map(RoomTypeDTO.ImageList::getImageUrl)
                        .findAny().orElse("");
                savePicInfo(hotelId, roomTypeCode, 3, roomImgUrl, "");
            }
        });
    }

    private void savePicInfo(String hotelId, String roomTypeCode, Integer type, String sourceUrl, String imageUrl) {
        HtHotelStdImage image = new HtHotelStdImage();
        image.setHotelId(hotelId);
        image.setRoomTypeCode(roomTypeCode);
        image.setImageType(type);
        image.setSourceUrl(sourceUrl);
        image.setImageUrl(imageUrl);
        htHotelStdImageService.save(image);
    }

    @Override
    public void syncRezencoHotelListTaskPush(String secretId, String secretKey, Long groupId) {
        try {
            if (redisUtil.setENx(RedisKeyConstant.HOTEL_MAIN_REZENCO_HOTELID_PUSH, PUSH_EXPIRY,
                    RedisKeyConstant.HOTEL_MAIN_REZENCO_HOTELID_PUSH)) {
                List<HotelInfoIdDTO> hotelInfoIdDTOS = rezenService.queryHotelListForCompany(secretId, secretKey, groupId);
                redisUtil.leftPushAll(RedisKeyConstant.HOTEL_MAIN_REZENCO_HOTELID_LIST,
                        hotelInfoIdDTOS.stream().map(HotelInfoIdDTO::getHotelId).collect(Collectors.toList()));
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    public void syncRezencoHotelListTaskPop(String secretId, String secretKey, Long groupId, Long companyId) {
        syncRezencoHotelListPopPol.execute(() -> new SyncRezencoHotelListTaskThread(secretId, secretKey, groupId, companyId));
    }

    @Override
    public void syncRezencoHotelListTask(String secretId, String secretKey, Long groupId, Long hotelId, Long companyId) {
        try {
            // 拿不到给我一直试
            while (true) {
                // 看看有没有被限流
                if (StringUtils.isNotBlank(
                        redisUtil.acquireToken(RedisKeyConstant.HOTEL_MAIN_REZENCO_STATIC_INFO_LIMIT_LOCK,
                                QPS_COUNT,
                                TIME_OUT))) {
                    // 酒店信息查询
                    HotelDetailsReq req = HotelDetailsReq.builder()
                            .hotelId(hotelId)
                            .groupId(groupId)
                            .build();
                    HotelDetailsResp hotel = rezenService.queryHotelDetails(req, secretId, secretKey);
                    if (hotel == null) {
                        return;
                    }
                    HtHotelStdInfo htHotelStdInfo = parseHotelInfoRezencoData(hotel);
                    LambdaUpdateWrapper<HtHotelStdInfo> wrapper = new LambdaUpdateWrapper<>();
                    wrapper.set(HtHotelStdInfo::getSourceStatus, htHotelStdInfo.getSourceStatus());
                    wrapper.set(HtHotelStdInfo::getSupportRestaurant, htHotelStdInfo.getSupportRestaurant());
                    wrapper.eq(HtHotelStdInfo::getHotelId, htHotelStdInfo.getHotelId());
                    // 基础信息
                    htHotelStdInfoService.saveOrUpdate(htHotelStdInfo, wrapper);
                    // 限流处理:休眠
                    Thread.sleep(1000L);
                    // 查询房型
                    ProductBriefListByCompanyIdReq roomTypeReq = ProductBriefListByCompanyIdReq.builder()
                            .companyIdList(Lists.newArrayList(companyId))
                            .groupId(groupId)
                            .hotelId(hotel.getHotelId())
                            .build();
                    List<ProductBriefListByCompanyIdResp> roomTypeList = rezenService.queryRoomTypeByCompanyId(roomTypeReq, secretId, secretKey);
                    if (CollectionUtils.isEmpty(roomTypeList)) {
                        return;
                    }
                    Optional.ofNullable(roomTypeList.get(0).getRoomTypeList()).orElse(new ArrayList<>()).forEach(roomType -> {
                        // 房型
                        HtRoomTypeStdInfo htRoomTypeStdInfo = new HtRoomTypeStdInfo();
                        htRoomTypeStdInfo.setHotelId(htHotelStdInfo.getHotelId());
                        htRoomTypeStdInfo.setRoomTypeName(roomType.getRoomtypNm());
                        htRoomTypeStdInfo.setRoomTypeCode(String.valueOf(roomType.getRoomtypId()));
                        htRoomTypeStdInfo.setRoomArea(roomType.getRoomArea());
                        htRoomTypeStdInfo.setMaxCheckIn(roomType.getOccupancyMax());
                        htRoomTypeStdInfo.setFloor(roomType.getRoomFloors());
                        Integer windowType = null;
                        if (roomType.getWindowType() != null) {
                            switch (roomType.getWindowType()) {
                                case 101:
                                    windowType = 1;
                                    break;
                                case 102:
                                    windowType = 0;
                                    break;
                                case 103:
                                    windowType = 2;
                                    break;
                                default:
                                    break;
                            }
                        }
                        htRoomTypeStdInfo.setWindowType(windowType);
                        Integer bedType = null;
                        if (CollectionUtils.isNotEmpty(roomType.getBedTypeList())) {
                            if (roomType.getBedTypeList().size() == 1) {
                                switch (roomType.getBedTypeList().get(0).getEntityNm()) {
                                    case "大床":
                                        bedType = 0;
                                        break;
                                    case "双人床":
                                        bedType = 4;
                                        break;
                                    case "单人床":
                                        bedType = 1;
                                        break;
                                    case "特大床":
                                        bedType = 3;
                                        break;
                                    default:
                                        break;
                                }
                            } else {
                                bedType = 5;
                            }

                        }
                        htRoomTypeStdInfo.setBedType(bedType);
                        htRoomTypeStdInfoService.saveOrUpdate(htRoomTypeStdInfo,
                                new LambdaQueryWrapper<HtRoomTypeStdInfo>().eq(HtRoomTypeStdInfo::getHotelId,
                                                htRoomTypeStdInfo.getHotelId())
                                        .eq(HtRoomTypeStdInfo::getRoomTypeCode, htRoomTypeStdInfo.getRoomTypeCode()));
                    });
                    break;
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    public void syncRezencoRatesTaskPush() {
        try {
            List<HtHotelStdInfo> htHotelStdInfos = htHotelStdInfoDao.selectList(
                    new LambdaQueryWrapper<HtHotelStdInfo>().eq(HtHotelStdInfo::getSourceCode,
                                    SourceEnum.REZENCO.getCode()).eq(HtHotelStdInfo::getSourceStatus, 1)
                            .eq(HtHotelStdInfo::getBookStatus, 1));
            if (CollectionUtils.isNotEmpty(htHotelStdInfos)
                    && redisUtil.lGetListSize(RedisKeyConstant.HOTEL_MAIN_REZENCO_RATES_LIST) <= 0) {
                redisUtil.leftPushAll(RedisKeyConstant.HOTEL_MAIN_REZENCO_RATES_LIST,
                        htHotelStdInfos.stream().map(HtHotelStdInfo::getHotelId).collect(Collectors.toList()));
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    public void syncRezencoRatesTaskPop(List<String> sourceIds, Integer days) {
        List<HtSourceInfo> sourceInfoList = htSourceInfoService.list(new LambdaQueryWrapper<HtSourceInfo>()
                .in(HtSourceInfo::getSourceId, sourceIds));
        syncRezencoRatesTaskPopPol.execute(() -> new SyncRezencoRatesTaskThread(sourceInfoList, days));
    }

    @Override
    public void syncRezencoRatesTask(String sourceId, String secretId, String secretKey, Long groupId, Long hotelId, Long companyId, String start, String end) {
        // 一律按照库存为1算 然后统一拉出数据处理 防止产品码修改
        htPriceCalendarRezenService.update(
                new LambdaUpdateWrapper<HtPriceCalendarRezen>().set(HtPriceCalendarRezen::getQuota, 1)
                        .eq(HtPriceCalendarRezen::getHotelId, rezenService.parseInnId3(hotelId)));
        // 拿不到给我一直试
        while (true) {
            // 看看有没有被限流
            if (StringUtils.isNotBlank(
                    redisUtil.acquireToken(RedisKeyConstant.HOTEL_MAIN_REZENCO_RATES_LIMIT_LOCK,
                            QPS_COUNT,
                            TIME_OUT))) {
                ProductListByCompanyIdReq productListByCompanyIdReq = ProductListByCompanyIdReq.builder()
                        .companyIdList(Lists.newArrayList(companyId))
                        .hotelId(hotelId)
                        .groupId(groupId)
                        .checkInDate(start)
                        .checkOutDate(end)
                        .roomQuantity(1)
                        .build();
                List<ProductListByCompanyIdResp> roomStatusList = rezenService.getRoomStatusByCompanyId(productListByCompanyIdReq, secretId, secretKey);
                if (CollectionUtils.isEmpty(roomStatusList)) {
                    return;
                }
                ProductListByCompanyIdResp roomStatus = roomStatusList.get(0);

                HtHotelStdInfo htHotelStdInfo = htHotelStdInfoDao.selectOne(
                        new LambdaQueryWrapper<HtHotelStdInfo>().eq(HtHotelStdInfo::getHotelId,
                                rezenService.parseInnId3(hotelId)));
                List<ProductListByCompanyIdResp.CancelRuleListBean> cancelRuleList = roomStatus.getCancelRuleList();
                Optional.ofNullable(roomStatus.getRoomTypeList()).orElse(new ArrayList<>()).forEach(roomStatu -> {
                    Optional.ofNullable(roomStatu.getProductList()).orElse(new ArrayList<>()).forEach(productList -> {
                        // 产品下线 直接处理下一个
                        if (productList.getStatusFlg() == 0) {
                            return;
                        }
                        // 价格日历
                        List<ProductListByCompanyIdResp.RoomTypeListBean.ProductListBean.RoomPriceListBean> roomPriceList = productList.getRoomPriceList();
                        if (CollectionUtils.isEmpty(roomPriceList)) {
                            return;
                        }
                        List<ProductListByCompanyIdResp.RoomTypeListBean.ProductListBean.RoomInventoryListBean> roomInventoryList = productList.getRoomInventoryList();
                        if (CollectionUtils.isEmpty(roomInventoryList)) {
                            return;
                        }
                        List<ProductListByCompanyIdResp.RoomTypeListBean.ProductListBean.RoomCancelRuleListBean> roomCancelRuleList = productList.getRoomCancelRuleList();
                        List<ProductListByCompanyIdResp.RoomTypeListBean.ProductListBean.BreakfastListBean> breakfastList = productList.getBreakfastList();
                        roomPriceList.forEach(roomPrice -> {
                            // 库存
                            ProductListByCompanyIdResp.RoomTypeListBean.ProductListBean.RoomInventoryListBean roomInventory =
                                    roomInventoryList.stream().filter(inventory -> inventory.getDay().equals(roomPrice.getDay()))
                                            .findFirst().orElse(null);

                            // build 参数
                            HtPriceCalendarRezen htPriceCalendarRezen = new HtPriceCalendarRezen();
                            htPriceCalendarRezen.setHotelId(rezenService.parseInnId3(hotelId));
                            htPriceCalendarRezen.setRoomTypeCode(String.valueOf(roomStatu.getRoomtypId()));
                            htPriceCalendarRezen.setRoomTypeName(roomStatu.getRoomtypNm());
                            htPriceCalendarRezen.setProductId(String.valueOf(productList.getProductId()));
                            htPriceCalendarRezen.setCalDate(DateUtil.parseDate(roomPrice.getDay(), "yyyy-MM-dd HH:mm:ss"));
                            htPriceCalendarRezen.setQuota(Objects.nonNull(roomInventory) ? roomInventory.getAvaRoomCnt() : 1);
                            htPriceCalendarRezen.setPurchasePrice(PriceUtil.fen2yuan(roomPrice.getPrice()));
                            htPriceCalendarRezen.setSourceId(sourceId);
                            // 早餐
                            ProductListByCompanyIdResp.RoomTypeListBean.ProductListBean.BreakfastListBean breakfast = Optional.ofNullable(breakfastList).orElse(new ArrayList<>()).stream()
                                    .filter(bf -> bf.getDay().equals(roomPrice.getDay())).findFirst().orElse(null);
                            htPriceCalendarRezen.setBreakfastCount(
                                    htHotelStdInfo.getSupportRestaurant() == 1 && Objects.nonNull(breakfast)
                                            ? breakfast.getBreakfastCnt() : 0);
                            ProductListByCompanyIdResp.RoomTypeListBean.ProductListBean.RoomCancelRuleListBean roomCancelRule =
                                    Optional.ofNullable(roomCancelRuleList).orElse(new ArrayList<>()).stream()
                                            .filter(rule -> rule.getDay().equals(roomPrice.getDay())).findFirst().orElse(null);

                            ProductListByCompanyIdResp.CancelRuleListBean cancelRule = Optional.ofNullable(cancelRuleList).orElse(new ArrayList<>()).stream()
                                    .filter(rule -> Objects.nonNull(roomCancelRule) && rule.getCancelRuleId()
                                            .equals(roomCancelRule.getCancelRuleId())).findFirst().orElse(null);

                            if (Objects.nonNull(cancelRule)) {
                                Integer cancelType = Optional.ofNullable(cancelRule).orElse(new ProductListByCompanyIdResp.CancelRuleListBean()).getCancelType();
                                if (cancelType != null) {
                                    switch (cancelType) {
                                        case 0:
                                            cancelType = 2;
                                            break;
                                        case 1:
                                            cancelType = 1;
                                            break;
                                        case 2:
                                            String type = Optional.ofNullable(cancelRule).orElse(new ProductListByCompanyIdResp.CancelRuleListBean()).getCancelRuleItemList()
                                                    .stream().map(ProductListByCompanyIdResp.CancelRuleListBean.CancelRuleItemListBean::getType).findAny().orElse(null);
                                            if ("NO_DEDUCTION".equals(type)) {
                                                cancelType = 4;
                                            } else if ("DEDUCT_BY_PERCENT".equals(type)) {
                                                String time = Optional.ofNullable(cancelRule).orElse(new ProductListByCompanyIdResp.CancelRuleListBean()).getCancelRuleItemList()
                                                        .stream().map(ProductListByCompanyIdResp.CancelRuleListBean.CancelRuleItemListBean::getTimeValue).findAny().orElse(null);
                                                htPriceCalendarRezen.setLastCancelTime(DateUtil.parseDate(time, "HH:mm:ss"));
                                                cancelType = 5;
                                            } else if ("DEDUCT_FIRST_NIGHT".equals(type)) {
                                                cancelType = 6;
                                            }
                                            break;
                                        default:
                                            break;
                                    }
                                    htPriceCalendarRezen.setCancelPolicyType(cancelType);

                                }
                                htPriceCalendarRezen.setCancelRule(JsonUtil.toString(roomCancelRule));
                            }
                            // 保存房态信息
                            htPriceCalendarRezenService.saveOrUpdate(htPriceCalendarRezen,
                                    new LambdaQueryWrapper<HtPriceCalendarRezen>()
                                            .eq(HtPriceCalendarRezen::getHotelId, htPriceCalendarRezen.getHotelId())
                                            .eq(HtPriceCalendarRezen::getRoomTypeCode, htPriceCalendarRezen.getRoomTypeCode())
                                            .eq(HtPriceCalendarRezen::getCalDate, htPriceCalendarRezen.getCalDate())
                                            .eq(HtPriceCalendarRezen::getProductId, htPriceCalendarRezen.getProductId())
                                            .eq(HtPriceCalendarRezen::getSourceId, htPriceCalendarRezen.getSourceId()));
                        });
                    });
                });
                break;
            }
        }
    }


    private HtHotelStdInfo parseHotelInfoData(HotelDetailsResp hotel) {
        if (hotel == null) {
            return null;
        }
        HtHotelStdInfo hotelInfoData = new HtHotelStdInfo();
        hotelInfoData.setSourceCode(SourceEnum.REZEN.getCode());
        hotelInfoData.setHotelId(rezenService.parseInnId(hotel.getHotelId()));
        hotelInfoData.setHotelName(hotel.getHotelName());
        hotelInfoData.setBrandCode(hotel.getBrandCode());
        hotelInfoData.setBrandName(hotel.getBrandName());
        hotelInfoData.setHotelAddress(hotel.getHotelAddress());
        hotelInfoData.setHotelTel(
                StringUtils.isBlank(hotel.getTelephone()) ? hotel.getMobilePhone() : hotel.getTelephone());
        String cityName = hotel.getCityName();
        if (StringUtils.isNotBlank(cityName) && cityName.endsWith("市")) {
            cityName = cityName.substring(0, cityName.length() - 1);
        }
        hotelInfoData.setProvinceName(hotel.getProvinceName());
        hotelInfoData.setCityCode(hotel.getCityCode());
        hotelInfoData.setCityName(cityName);
        hotelInfoData.setIntroduction(hotel.getIntroduction());
        hotelInfoData.setSourceStatus(hotel.getStatus() == 1 ? 1 : 0);
        hotelInfoData.setBookStatus(hotel.getStatus() == 1 ? 1 : 0);
        hotelInfoData.setSupportForeignGuest(null);
        hotelInfoData.setOverseas(0);
        hotelInfoData.setLatitude(BigDecimal.valueOf(hotel.getLatitude()));
        hotelInfoData.setLongitude(BigDecimal.valueOf(hotel.getLongitude()));
        hotelInfoData.setMapPointType(hotel.getMapType());
        // 早餐
        HotelDetailsResp.AmenitiesBean amenitie = Optional.ofNullable(hotel.getAmenities()).orElse(new ArrayList<>()).stream()
                .filter(amenities -> "Breakfast".equals(amenities.getAmentiesCode())).findAny().orElse(null);
        hotelInfoData.setSupportRestaurant(Objects.nonNull(amenitie) ? 1 : 0);
        hotelInfoData.setExtra(JsonUtil.toString(hotel));
        return hotelInfoData;
    }

    private HtHotelStdInfo parseHotelInfoRezencoData(HotelDetailsResp hotel) {
        if (hotel == null) {
            return null;
        }
        HtHotelStdInfo hotelInfoData = new HtHotelStdInfo();
        hotelInfoData.setSourceCode(SourceEnum.REZENCO.getCode());
        hotelInfoData.setHotelId(rezenService.parseInnId3(hotel.getHotelId()));
        hotelInfoData.setHotelName(hotel.getHotelName());
        hotelInfoData.setBrandCode(hotel.getBrandCode());
        hotelInfoData.setBrandName(hotel.getBrandName());
        hotelInfoData.setHotelAddress(hotel.getHotelAddress());
        hotelInfoData.setHotelTel(
                StringUtils.isBlank(hotel.getTelephone()) ? hotel.getMobilePhone() : hotel.getTelephone());
        String cityName = hotel.getCityName();
        if (StringUtils.isNotBlank(cityName) && cityName.endsWith("市")) {
            cityName = cityName.substring(0, cityName.length() - 1);
        }
        hotelInfoData.setProvinceName(hotel.getProvinceName());
        hotelInfoData.setCityCode(hotel.getCityCode());
        hotelInfoData.setCityName(cityName);
        hotelInfoData.setIntroduction(hotel.getIntroduction());
        hotelInfoData.setSourceStatus(hotel.getStatus() == 1 ? 1 : 0);
        hotelInfoData.setBookStatus(hotel.getStatus() == 1 ? 1 : 0);
        hotelInfoData.setSupportForeignGuest(null);
        hotelInfoData.setOverseas(0);
        hotelInfoData.setLatitude(BigDecimal.valueOf(hotel.getLatitude()));
        hotelInfoData.setLongitude(BigDecimal.valueOf(hotel.getLongitude()));
        hotelInfoData.setMapPointType(hotel.getMapType());
        // 早餐
        HotelDetailsResp.AmenitiesBean amenitie = Optional.ofNullable(hotel.getAmenities()).orElse(new ArrayList<>()).stream()
                .filter(amenities -> "Breakfast".equals(amenities.getAmentiesCode())).findAny().orElse(null);
        hotelInfoData.setSupportRestaurant(Objects.nonNull(amenitie) ? 1 : 0);
        hotelInfoData.setExtra(JsonUtil.toString(hotel));
        return hotelInfoData;
    }
}
